package com.io.io03;

import java.io.*;

public class CopyDirectory {
    // 定义成 static 属性，保证在 traversal 中可以读取
    static File srcFile = new File("D:\\课程");
    static File destFile = new File("D:\\课程\\dest");

    public static void main(String[] args) throws Exception {

        traversal(srcFile);
    }

    private static void traversal(File dirFile) throws Exception {
        File[] files = dirFile.listFiles();
        if (files == null) {
            return;
        }

        for (File file : files) {
            // 怎么得到相对位置：利用 srcFile 的 绝对路径、destFile 的绝对路径、file 的绝对路径
//            System.out.println(srcFile.getCanonicalPath());
//            System.out.println(file.getCanonicalPath());
//            System.out.println(destFile.getCanonicalPath());
//            System.out.println("================================");
            String srcFilePath = srcFile.getCanonicalPath();
            String filePath = file.getCanonicalPath();
            String destPath = destFile.getCanonicalPath();

            String relativePath = filePath.substring(srcFilePath.length());
            String destFilePath = destPath + relativePath;
//            System.out.println(destFilePath);
            File oneDestFile = new File(destFilePath);

            if (file.isDirectory()) {
                // 是目录时，直接创建目录
                oneDestFile.mkdir();    // 我们可以保证其父目录一定存在
                traversal(file);
            } else if (file.isFile()) {
                copyFile(file, oneDestFile);
            }
        }
    }

    private static void copyFile(File srcFile, File destFile) throws Exception {
        // 0. 用于统计复制速度
        long startedAt = System.currentTimeMillis();    // 获取当前时间戳（ms）

        // 1. 准备好搬数据的桶
        byte[] buf = new byte[1024];

        // 2. 打开两个文件
        int count = 0;
        try (InputStream is = new FileInputStream(srcFile)) {
            try (OutputStream os = new FileOutputStream(destFile)) {
                // 3. 不断地用桶从 is 接水，倒入 os 中
                while (true) {
                    int n = is.read(buf);
                    count += n;
                    // System.out.printf("已经复制了 %d 字节的数据\n", count);
                    if (n == -1) {
                        // 全部读完了，可以中止循环了
                        break;
                    }

                    // 直接将读入的数据，原封不同的写入 os 中
                    os.write(buf, 0, n);
                }

                // 4. 冲刷缓冲区
                os.flush();
            }
        }

        // 0. 用于统计复制速度
        long endedAt = System.currentTimeMillis();    // 获取当前时间戳（ms）
        long ms = endedAt - startedAt;
        double s = ms / 1000.0;
//        System.out.printf("复制共消耗了: %.3f 秒\n", s);
    }
}
